package com.jichangxiu.common.utils;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * CacheUtils:
 *
 * @author Administrator
 * @create 2023-04-10 9:14
 */
@Slf4j
public class CacheUtils {

    /**
     * 缓存操作对象
     */
    private static final LoadingCache<String, Object> cache = loadCache(new CacheLoader<String, Object>() {
        @Override
        public Object load(String key) {
            // 从数据库加载，当key对应的value不存在时的处理逻辑
            return null;
        }
    });

    /**
     * 缓存设置
     * 缓存项最大数量：10000
     * 缓存有效时间（天）：1
     */
    private static LoadingCache<String, Object> loadCache(CacheLoader<String, Object> cacheLoader) {
        return CacheBuilder.newBuilder()
                .concurrencyLevel(Runtime.getRuntime().availableProcessors())
                // 设置初始容量
                .initialCapacity(1000)
                // 缓存池大小
                .maximumSize(10000)
                // 设置 设定时间 后 刷新缓存
                .refreshAfterWrite(1, TimeUnit.DAYS)
                .build(cacheLoader);
    }

    /**
     * 设置缓存值
     * 若已有该key值，则会先移除(会触发removalListener移除监听器)，再添加
     */
    public static void set(String key, Object value) {
        put(key, value);
    }

    /**
     * 设置缓存值
     * 若已有该key值，则会先移除(会触发removalListener移除监听器)，再添加
     */
    public static void put(String key, Object value) {
        if (StrUtils.isBlank(key) || value == null) {
            return;
        }
        try {
            cache.put(key, value);
        } catch (Exception e) {
            log.error("设置缓存值出错", e);
        }
    }

    /**
     * 获取缓存值
     * 如果键不存在值，将调用CacheLoader的load方法，将load方法的返回值加载到缓存
     */
    public static Object get(String key) {
        Object token = null;
        try {
            token = cache.get(key);
        } catch (Exception e) {
            log.warn("未获取到缓存值");
        }
        return token;
    }

    public static void remove(String key) {
        try {
            cache.invalidate(key);
        } catch (Exception e) {
            log.warn("删除缓存 " + key + " 失败");
        }
    }

    public static void clean() {
        try {
            cache.invalidateAll();
        } catch (Exception e) {
            log.warn("删除所有缓存失败");
        }
    }

}
